// let a: string = '3'
// console.log(a)
/**
 * 
 * Set:

  new Set(): 创建一个新的Set对象
  add(value): 向Set对象中添加一个新的值
  delete(value): 从Set对象中删除一个值
  has(value): 检查Set对象中是否存在指定的值
  size: 获取Set对象中的值的数量
  clear(): 从Set对象中删除所有值

  Map:

  new Map(): 创建一个新的Map对象
  set(key, value): 向Map对象中添加一个键值对
  get(key): 根据键获取Map对象中的值
  delete(key): 从Map对象中删除一个键值对
  has(key): 检查Map对象中是否存在指定的键
  size: 获取Map对象中的键值对数量
  clear(): 从Map对象中删除所有键值对
 * 
 */
// Set
// 1.去重
const arr = [1, 2, 3, 1, 2, 4, 5];
const uniqueArr = [...new Set(arr)];
console.log(uniqueArr); // [1, 2, 3, 4, 5]

// 写法二 使用 Array.from() 将Set类型转换回数组。
const arr2 = [1, 2, 3, 1, 2, 4, 5];
const set2 = new Set(arr2);
const uniqueArr2 = Array.from(set2);
console.log(uniqueArr2); // [1, 2, 3, 4, 5]


// 2.优化数据查找
const dataSet = new Set([1, 2, 3, 4, 5]);

if (dataSet.has(3)) {
  console.log('数据已经存在');
} else {
  console.log('数据不存在');
}

// 3.并集、交集、差集
const setA = new Set([1, 2, 3]);
const setB = new Set([2, 3, 4]);

// 并集
const union = new Set([...setA, ...setB]);
console.log(union); // Set {1, 2, 3, 4}

// 交集
const intersection = new Set([...setA].filter(x => setB.has(x)));
console.log(intersection); // Set {2, 3}

// 差集
const difference = new Set([...setA].filter(x => !setB.has(x)));
console.log(difference); // Set {1}

// 4.模糊搜索
const data = ['apple', 'banana', 'pear', 'orange'];

// 搜索以 "a" 开头的水果
const result = Array.from(new Set(data.filter(item => /^a/i.test(item))));
console.log(result); // ["apple"]


// 5.使用 Set 替代数组实现队列和栈
// 使用 Set 实现队列
const queue = new Set();
queue.add(1);
queue.add(2);
queue.add(3);
queue.delete(queue.values().next().value); // 删除第一个元素
console.log(queue); // Set(2) { 2, 3 }

// 使用 Set 实现栈
const stack = new Set();
stack.add(1);
stack.add(2);
stack.add(3);
stack.delete([...stack][stack.size - 1]); // 删除最后一个元素
console.log(stack); // Set(2) { 1, 2 }

// Map
// 将 Map 转换为对象
const map = new Map().set('key1', 'value1').set('key2', 'value2');
const obj = Object.fromEntries(map);
console.log(obj);
// 将 Map 转换为数组
const map1 = new Map().set('key1', 'value1').set('key2', 'value2');
const array1 = Array.from(map1);
console.log(array1);
// 记录数据的顺序
const map3 = new Map();
map3.set('a', 1);
map3.set('d', 4);
map3.set('b', 2);
map3.set('c', 3);

for (const [key, value] of map3) {
  console.log(key, value);
}
// Output: a 1, b 2, c 3, d 4
// 统计数组中元素出现次数
const arr5 = [1, 2, 3, 1, 2, 4, 5];

const countMap = new Map();
arr.forEach(item => {
  countMap.set(item, (countMap.get(item) || 0) + 1);
});

console.log(countMap.get(1)); // 2
console.log(countMap.get(2)); // 2
console.log(countMap.get(3)); // 1

// 统计字符出现次数
const str = 'hello world';
const charCountMap = new Map();
for (let char of str) {
  charCountMap.set(char, (charCountMap.get(char) || 0) + 1);
}
console.log(charCountMap); // Map { 'h' => 1, 'e' => 1, 'l' => 3, 'o' => 2, ' ' => 1, 'w' => 1, 'r' => 1, 'd' => 1 }

// 缓存计算结果
const cache = new Map();
function fibonacci(n:number):number {
  if (n === 0 || n === 1) {
    return n;
  }
  if (cache.has(n)) {
    return cache.get(n);
  }
  const result = fibonacci(n - 1) + fibonacci(n - 2);
  cache.set(n, result);
  return result;
}
console.log(fibonacci(10)); // 55

//使用 Map 进行数据的分组
const students = [
  { name: "Tom", grade: "A" },
  { name: "Jerry", grade: "B" },
  { name: "Kate", grade: "A" },
  { name: "Mike", grade: "C" },
];

// 使用 Map 进行数据的分组
const gradeMap = new Map();
students.forEach((student) => {
  const grade = student.grade;
  if (!gradeMap.has(grade)) {
    gradeMap.set(grade, [student]);
  } else {
    gradeMap.get(grade).push(student);
  }
});

console.log(gradeMap.get("A")); // [{ name: "Tom", grade: "A" }, { name: "Kate", grade: "A" }]

// 使用 Map 过滤符合条件的对象
const users = [
  { name: 'Alice', age: 22 },
  { name: 'Bob', age: 18 },
  { name: 'Charlie', age: 25 }
];
const userMap = new Map(users.map(user => [user.name, user]));
const result3 = users.filter(user => userMap.has(user.name) && user.age > 20);
console.log(result3); // [{ name: 'Alice', age: 22 }, { name: 'Charlie', age: 25 }]

